#include <typeinfo>

#include "prototype.h"

std::string Prototype::functorName () {
  if(type == Tree::ID) {
    char ret[3] = "  ";
    ret[0] = u.ops[0];
    ret[1] = u.ops[1];
    return ret;
  }

  return functor ? functor->name : "";
}

Prototype Prototype::get (Node &node) {
  Node *final = node.final ();
  if(typeid(*final) == typeid(Atom))
    return Prototype (static_cast<Atom*> (final));
  else if(typeid(*final) == typeid(Tree)) // Operator as functor
    return Prototype (static_cast<Tree*> (final)->ops);
  else if(typeid(*final) == typeid(Tuple)) {
    Tuple &tuple = *static_cast<Tuple*> (final); // First node as functor
    if(!tuple.nodes.empty ()) { // Useful for embedding closure in first node
      Prototype p = get (*tuple.nodes[0]);
      return Prototype (p.functor, tuple.nodes.size ());
    } else
      return Prototype (Atom::create (""), 0);
  }
  else
    return Prototype (); // This prototype matches anything
}

Prototype Prototype::getFromRule (Node &node) {
  if(node.type () == Tree::ID) {
    Tree &tree = *static_cast<Tree*> (node.final ());
    if(equalOp (tree.ops, inferenceOperator))
      return get (*tree.left);
  }
  return get (node);
}
